package cn.wolfcode.shop.service;

import cn.wolfcode.shop.domain.ProductSku;
import cn.wolfcode.shop.domain.ProductSkuProperty;
import cn.wolfcode.shop.domain.SkuProperty;
import cn.wolfcode.shop.domain.SkuPropertyValue;
import cn.wolfcode.shop.mapper.ProductSkuMapper;
import cn.wolfcode.shop.mapper.ProductSkuPropertyMapper;
import cn.wolfcode.shop.mapper.SkuPropertyMapper;
import cn.wolfcode.shop.vo.GenerateSkuVo;
import cn.wolfcode.shop.vo.ProductVo;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service@Transactional
public class ProductSkuServiceImpl implements IProductSkuService {
    @Autowired
    private SkuPropertyMapper skuPropertyMapper;
    @Autowired
    private ProductSkuMapper productSkuMapper;
    @Autowired
    private ProductSkuPropertyMapper productSkuPropertyMapper;

    @Override
    public List<Map> generateSku(GenerateSkuVo generateSkuVo) {
        //获取sku属性值集合
        List<SkuPropertyValue> skuPropertyValueList = generateSkuVo.getSkuPropertyValueList();
        //根据skuPropertyId()分组
        Map<Long, List<SkuPropertyValue>> map = new HashMap<>();
        for (SkuPropertyValue spv : skuPropertyValueList) {
            List<SkuPropertyValue> skuPropertyValueListTemp = map.get(spv.getSkuPropertyId());
            if (skuPropertyValueListTemp == null) {
                skuPropertyValueListTemp = new ArrayList<>();
                map.put(spv.getSkuPropertyId(), skuPropertyValueListTemp);
            }
            //skuPropertyValueListTemp不为空
            skuPropertyValueListTemp.add(spv);
        }
        //源数据
        List<List<SkuPropertyValue>> sourceData = new ArrayList<>(map.values()); //可以获取到map value的集合
        //目标数据
        List<List<SkuPropertyValue>> targetData = new ArrayList<>();
        //生成sku组合
        generateSkuRecursion(sourceData, targetData, 0, Collections.EMPTY_LIST);
        List<Map> skuData = new ArrayList<>();
        Map record;
        String skuCodePrefix = skuPropertyMapper.getCodePrefix(generateSkuVo.getProduct().getCatalog().getId()) + generateSkuVo.getProduct().getId();
        for (int i = 0; i < targetData.size(); i++){
            record = new HashMap();
            record.put("code", skuCodePrefix + (i+1));
            record.put("price", generateSkuVo.getProduct().getBasePrice());
            for (int j = 0; j < targetData.get(i).size(); j++){
                record.put(targetData.get(i).get(j).getSkuPropertyId()+"", targetData.get(i).get(j).getValue());
            }
            skuData.add(record);
        }
        return skuData;
    }

    private void generateSkuRecursion(List<List<SkuPropertyValue>> sourceData, List<List<SkuPropertyValue>> targetData, int level, List<SkuPropertyValue> appendData) {
        //判断是否是最后一层循环
        if (level < sourceData.size() -1){
            //不是
            List<SkuPropertyValue> skuPropertyValueList = sourceData.get(level);
            for (SkuPropertyValue spv : skuPropertyValueList) {
                List<SkuPropertyValue> listTemp = new ArrayList<>(appendData);
                listTemp.add(spv);
                generateSkuRecursion(sourceData, targetData, level + 1, listTemp);
            }
        } else {
            //是
            List<SkuPropertyValue> skuPropertyValueList = sourceData.get(level);
            for (SkuPropertyValue spv : skuPropertyValueList) {
                List<SkuPropertyValue> listTemp = new ArrayList<>(appendData);
                listTemp.add(spv);
                targetData.add(listTemp);
            }
        }
    }

    @Override
    public void save(ProductVo productVo) {
        List<ProductSku> productSkuList = productVo.getProductSkuList();
        for (ProductSku ps : productSkuList) {
            ps.setProductId(productVo.getProduct().getId());
            productSkuMapper.insert(ps);
            for (ProductSkuProperty psp : ps.getProductSkuPropertyList()) {
                psp.setProductSkuId(ps.getId());
                productSkuPropertyMapper.insert(psp);
            }
        }
    }

    @Override
    public List<ProductSku> getByProductId(Long productId) {
        return productSkuMapper.getByProductId(productId);
    }

    @Override
    public ProductSku get(Long productSkuId) {
        return productSkuMapper.selectByPrimaryKey(productSkuId);
    }
}
